const modal = require('./modal')
const util = require('./util')
const schema = modal.schema
const xlsx = require('node-xlsx')
const _ = require('lodash')
const config = require('./config')
/**
 * 标题和key映射表
 * @type {[*]}
 */
const namMap = [
  {
    name: '创建时间',
    key: 'orderDate',
    type: 'date'
  },
  {
    name: '商品信息',
    key: 'goodName'
  },
  {
    name: '商品ID',
    key: 'goodId'
  },
  {
    name: '商品数',
    key: 'qty'
  },
  {
    name: '付款金额',
    key: 'pay'
  },
  {
    name: '佣金比率',
    key: 'commissionRate'
  },
  {
    name: '分成比率',
    key: 'tbkShareRate'
  },
  {
    name: '佣金金额',
    key: 'commission'
  },
  {
    name: '补贴金额',
    key: 'subsidy'
  },
  {
    name: '补贴比率',
    key: 'subsidyRate'
  },
  {
    name: '补贴类型',
    key: 'subsidyType'
  },
  {
    name: '广告位ID',
    key: 'adId'
  },
  {
    name: '广告位名称',
    key: 'adName'
  },
  {
    name: '订单编号',
    key: 'sheet'
  },
  {
    name: '结算时间',
    key: 'cashDate',
    type: 'date'
  },
  {
    name: '效果预估',
    key: 'forecastIncome'
  },
  {
    name: '订单状态',
    key: 'orderState'
  }
]

/**
 * 导入订单
 */
Parse.Cloud.define('uploadDetail', async (request, response) => {
  const tbkId = request.params.tbkId  // 淘宝客账号
  const ordersFile = request.params.file  // 文件的地址
  if (!tbkId) {
    return response.error('请选择淘宝客账号')
  }
  if (!ordersFile) {
    return response.error('请上传文件')
  }
  try {
    // 获取文件
    const file = await Parse.Cloud.httpRequest({
      url: ordersFile.url()
    })
    // 解释文件流
    const workSheets = xlsx.parse(file.buffer)
    if (!workSheets || workSheets.length === 0) {
      return response.error('文件格式不正确')
    }
    // 解释excel文件，提取所需要的数据，并转化成数据库存储格式
    const workSheetsMap = workSheets.reduce((prevPage, currentPage) => {
      const data = currentPage.data
      if (data.length === 0) {
        return response.error('文件格式不正确')
      }
      const names = data[0]  // 标题行
      const orders = data.filter((item, index) => index !== 0) // 数据行
      // 根据标题行，获取对应key的index值
      const keyIndex = namMap.map((item) => {
        const index = names.findIndex((name) => name === item.name)
        return {
          key: item.key,
          type: item.type,
          index
        }
      })
      // 根据index值，获取所需要数据
      const pageData = orders.map((order) => {
        const tbk = schema.tbk()
        tbk.id = tbkId
        const row = keyIndex.reduce((prev, current) => {
          if (current.type === 'date') { // 如果为时间类型，转换为时间格式
            prev.set(current.key, order[current.index] ? new Date(order[current.index]) : null)
          } else {
            prev.set(current.key, order[current.index])
          }
          return prev
        }, schema.order())
        row.set('tbk', tbk)
        return row
      })
      return prevPage.concat(pageData)
    }, [])
    console.log('workSheetsMap', workSheetsMap.length)
    // 保存解释出来的数据
    const query = schema.order().query().limit(1000000)
    const groupQuery = schema.group().query().limit(1000000) // 所属的群
    const sheets = []
    const groupCodes = []
    for (let i = 0, len = workSheetsMap.length; i < len; i++) {
      const currentOrder = workSheetsMap[i] // 当前订单
      const sheet = currentOrder.get('sheet')
      if (sheet) {
        sheets.push(currentOrder.get('sheet'))
      }
      const code = parseInt(_.trim(_.last(currentOrder.get('adName').split('_'))), 10)
      if (code) {
        groupCodes.push(code)
      }
    }
    const findExistOrders = query.containedIn('sheet', sheets).select('sheet').find()
    const findGroups = groupQuery.containedIn('groupCode', groupCodes).select('groupCode').find()
    const existOrders = await findExistOrders
    const groups = await findGroups

    const updateCount = existOrders.length
    const addCount = workSheetsMap.length - updateCount

    workSheetsMap.forEach((item) => {
      const code = parseInt(_.trim(_.last(item.get('adName').split('_'))), 10)
      const sheet = item.get('sheet')
      if (code) {
        const currentGroup = groups.find(group => group.get('groupCode') === code)
        if (currentGroup) {
          item.set('group', currentGroup)
        }
      }
      const existOrder = existOrders.find(order => order.get('sheet') === sheet)
      if (existOrder) {
        item.id = existOrder.id
      } else {
        item.set('status', 0)
      }
    })

    console.log('worksheetsMap', workSheetsMap.slice(0, 10))
    await Parse.Object.saveAll(workSheetsMap)
    response.success(`成功导入${updateCount + addCount}条数据，其中更新${updateCount}条，新增${addCount}条`)
  } catch (err) {
    response.error(err.message)
  }
})
/**
 * 明细列表查询
 */
Parse.Cloud.define('getOrders', async (request, response) => {
  const { currentPage, pageSize, condition } = request.params
  const query = schema.order().query()
  let orderList = []
  query.limit(pageSize)
  query.skip((currentPage - 1) * pageSize)
  query.descending('updatedAt')  // 以更新时间排序
  query.include('group.member') // 查找组及会员
  query.include('tbk') // 查找所属淘客
  // 查询条件
  if (condition) {
    const { tbkId, groupId, status, orderDate, sheet } = condition
    // 指定淘客的订单
    if (tbkId) {
      const tbk = schema.tbk()
      tbk.id = tbkId
      query.equalTo('tbk', tbk)
    }
    // 查询指定群的订单
    if (groupId) {
      const group = schema.group()
      group.id = groupId
      query.equalTo('group', group)
    }
    // 查询指定状态的订单
    if (typeof status === 'number') {
      query.equalTo('status', status)
    }
    // 订单号查询
    if (sheet) {
      query.equalTo('sheet', sheet)
    }
    // 按名称查询
    if (orderDate && orderDate[0] && orderDate[1]) {
      query.greaterThanOrEqualTo('orderDate', orderDate[0])
      query.lessThanOrEqualTo('orderDate', orderDate[1])
    }
  }
  try {
    const groupFind = query.find()
    const groupCount = query.count()  // 计算条数
    const result = await groupFind
    const count = await groupCount
    orderList = result.map((item) => {
      const currentOrder = util.mapAttributes(item, ['createdAt', 'sheet', 'status', 'cashDate', 'forecastIncome', 'pay', 'goodName', 'commissionRate', 'commission', 'qty', 'orderDate', 'orderState'])
      currentOrder.id = item.id
      const tbk = item.get('tbk')
      const group = item.get('group')
      // 获取淘客信息
      if (tbk) {
        currentOrder.tbkUsername = tbk.get('username')
        currentOrder.tbkId = tbk.id
      }
      // 获取群信息
      if (group) {
        currentOrder.groupName = group.get('name')
        currentOrder.groupId = group.id
        const member = group.get('member')
        // 获取会员信息
        if (member) {
          currentOrder.member = member.get('name')
          currentOrder.memberId = member.id
          currentOrder.level = member.get('level')
          currentOrder.shareRate = member.get('shareRate')
        }
      }
      return currentOrder
    })
    response.success({
      total: count,   // 总数量
      totalPage: Math.ceil(count / pageSize),  // 总页数
      currentPage,   // 当前页
      pageSize,   // 每页数量
      data: orderList   // 查询出来的结果集
    })
  } catch (err) {
    response.error(err.message)
  }
})
/**
 * 获取自身的订单和下级订单
 */
Parse.Cloud.define('getOrdersAndSubOrdersByMember', async (request, response) => {
  const { currentPage, pageSize, condition } = request.params
  if (!condition || !condition.id) {
    return response.error('请提供会员ID')
  }
  const member = schema.member()
  member.id = condition.id
  const query = schema.order().query()
  const groupQuery = schema.group().query()  // 群查询
  let orderList = []
  query.limit(pageSize)
  query.skip((currentPage - 1) * pageSize)
  query.descending('updatedAt')  // 以更新时间排序
  query.include('group.member') // 查找组及会员
  query.include('tbk') // 查找所属淘客

  const subMembersAndLevel = await util.getSubMembers(member, 2) // 会员及会员对应的层级
  const members = subMembersAndLevel.map((item) => {  // 下级会员
    const subMember = schema.member()
    subMember.id = item.id
    return subMember
  })
  members.push(member)
  groupQuery.containedIn('member', members)
  groupQuery.equalTo('status', 1)
  const groups = await groupQuery.find()  // 查找会员及下级会员所有的群
  query.containedIn('group', groups)
  try {
    const orderFind = query.find()
    const orderCount = query.count()
    const result = await orderFind
    const count = await orderCount
    // 组合数据
    orderList = result.map((item) => {
      const currentOrder = util.mapAttributes(item, ['createdAt', 'sheet', 'status', 'cashDate', 'forecastIncome', 'pay', 'goodName', 'commissionRate', 'commission', 'qty', 'orderDate', 'orderState'])
      currentOrder.id = item.id
      const group = item.get('group')
      if (group) {
        // 群数据
        currentOrder.groupId = group.id
        currentOrder.groupName = group.get('name')
        const groupMember = group.get('member')
        // 会员数据
        if (groupMember) {
          const memberId = groupMember.id
          const level = groupMember.get('level')
          const shareRate = config.shareRate[`level${level}`]  // 获取对应等级的分成比例
          currentOrder.member = groupMember.get('name')
          currentOrder.memberId = memberId
          if (memberId === condition.id) {  // 如果是本人，则获取本人的分成比例
            currentOrder.shareRate = shareRate.self
            currentOrder.groupOwner = '本人'
          } else { // 否则，获取下级对应的分成比例
            const subMember = subMembersAndLevel.find((item) => item.id === memberId)
            const subShareRate = config.shareRate[`level${subMember.level}`]
            currentOrder.shareRate = subShareRate[`parent${subMember.deep}`]
            currentOrder.groupOwner = '我的下级代理'
          }
        }
        // 计算本人的佣金
        currentOrder.myForecastIncome = (currentOrder.forecastIncome * currentOrder.shareRate / 100).toFixed(4)
      }
      return currentOrder
    })
    response.success({
      total: count,   // 总数量
      totalPage: Math.ceil(count / pageSize),  // 总页数
      currentPage,   // 当前页
      pageSize,   // 每页数量
      data: orderList
    })
  } catch (err) {
    response.error(err.message)
  }
})
/**
 * 订单核算
 */
Parse.Cloud.define('checkOrder', async (request, response) => {
  const { id, status } = request.params
  if (!id) {
    return response.error('请提供需要核算的订单ID')
  }
  if (typeof status !== 'number') {
    return response.error('状态非法')
  }
  const order = schema.order()
  order.id = id
  order.set('status', status)
  try {
    // 如果核算通过，则将收存入到对应的账号，作为账号余额
    if (status === 1) {
      const deep = config.deep  // 代理层级
      const parentKey = new Array(deep).fill('parent').join('.') // 拼接成'parent.parent'的形式
      const query = order.query()
      query.equalTo('objectId', id)
      query.include(`group.member.${parentKey}`)
      const currentOrder = await query.first()  // 当前订单
      if (currentOrder) {
        const forecastIncome = currentOrder.get('forecastIncome')  // 预估收入
        const currentGroup = currentOrder.get('group')  // 订单所属的群
        const currentMember = currentGroup.get('member') // 群所属的会员
        const currentMemberLevel = currentMember.get('level')  // 会员的代理等级
        const shareRateConfig = config.shareRate[`level${currentMemberLevel}`]  // 会员的分成比例配置
        const members = []  // 能参与该订单分成的所有会员
        members.push({
          id: currentMember.id,
          shareRate: currentMember.get('shareRate'),
          status: currentMember.get('status'),
          type: 'self'
        })
        // 上级所得到的分成
        for (let current = currentMember.get('parent'), currentDeep = 1; current; current = current.get('parent'), currentDeep++) {
          members.push({
            id: current.id,
            shareRate: shareRateConfig[`parent${currentDeep}`],
            status: current.get('status'),
            type: 'parent'
          })
        }
        for (let i = 0, len = members.length; i < len; i++) {
          const member = members[i]
          if (member.status === 1) {  // 只有审核通过的会员才能参与分成
            const memberSchema = schema.member()
            memberSchema.id = member.id
            const accountQuery = schema.account().query() // 账户查询
            accountQuery.equalTo('member', memberSchema)  // 会员对应的账户
            const currentAccount = await accountQuery.first()
            const selfIncomes = currentAccount.get('selfIncomes') || 0  // 本人收益
            const subIncomes = currentAccount.get('subIncomes') || 0  // 下级给本人的收益
            const incomes = parseFloat((forecastIncome * member.shareRate / 100).toFixed(4))
            if (member.type === 'self') {
              currentAccount.set('selfIncomes', parseFloat((selfIncomes + incomes).toFixed(4)))
            } else {
              currentAccount.set('subIncomes', parseFloat((subIncomes + incomes).toFixed(4)))
            }
            await currentAccount.save()
          }
        }
      }
    }
    await order.save()
    response.success({
      code: 1
    })
  } catch (err) {
    response.error(err.message)
  }
})
